//TP5

//关闭自动添加Url::root("index.php");
//域名必须留index.php
//index为方法,参数['type'=>'dowonload','name'=>$vo.name])}
url('index',['type'=>'dowonload','name'=>$vo.name])}
#$
$this->success("$info", 'index/backup/index');
#$
//循环输出到视图
{volist name="data" id="val"}
{$val.id}:{$val.c_name}<br/>
<img src="/static/imgs/{$val.url}"/>
{/volist}

#$
//TP5生命周期
入口文件->引导文件->注册自动加载->注册错误和异常机制->应用初始化->URL访问检测->路由检测->分发请求->响应输出->应用结束
#$



#$
//获取请求类型
public function getType(Request $request){
echo'请求方法：'.$request->method().'<br/>';
echo'资源类型：'.$request->type().'<br/>';
echo'访问ip地址：'.$request->ip().'<br/>';
echo'是否AJax请求：'.var_export($request->isAjax(),true).'<br/>';
echo'请求参数：';
dump($request->param());
echo'请求参数：仅包含name';
dump($request->only(['name']));
echo'请求参数：排除name';
dump($request->except(['name']));
}
#$



#$
//Url生成完整
{:url('member_view','','html',request()->domain())}
#$




#$
//过滤数据
public function guolv(Request $request){
//所有符号转为实体
$request->filter("htmlspecialchars");
//处理转换单双引号
$request->filter("strip_tags");
//过滤单个变量并且md5加密
$md5=$request->post("user","","htmlspecialchars,md5");
dump($md5);
return view();
}






#$
//查询数据
    public function data()
    {
    	//系统构造器查询
    $db=new Db;//实例化系统数据库类
    $data=$db::table("user")->select();
    dump($data);
    echo "</hr>";
        //sql语句查询数据
        $data1=$db::query("select *from user");
        dump($data1);
    echo "</hr>";
    	}
    
    
    
    
    
    #$
   //数据模型Model连接数据库
   <?php          
namespace app\index\model;
use think\Model;
class User extends Model {
//设置当前模型对应的完整数据表名称
protected$table='user';
//设置当前模型的数据库连接
protected$connection=[
//数据库类型
'type'=>'mysql',
//服务器地址
'hostname'=>'127.0.0.1',
//数据库名
'database'=>'m752753127',
//数据库用户名
'username'=>'root',
//数据库密码
'password'=>'',
//数据库编码默认采用utf8
'charset'=>'utf8',
//数据库表前缀
'prefix'=>'think_',
//数据库调试模式
'debug'=>false,
];
}







#$
//控制器中使用数据模型Model
public function user(){
$user=new \app\index\model\User();
dump($user::all());
}




#$
$sql=Db::getLastsql();//获取最后一次执行的sql语句







#$

<?php
namespace app\index\controller;
use think\Controller;
use think\Request;
use think\Db;
class User extends controller
{
    public function index()
    {
    return "User控制器。。。";
    }
    
    //User表中添加数据
    //
    public function insert(){
date_default_timezone_set('PRC');
$time=date('Y-m-d H:i:s');
//$bool=Db::execute("insert into user values(null,'majun','ssx','','','')");//方式1
//dump($bool);
//$bool=Db::execute("insert into user values(null,?,?,?,?,?)",[1,1,1,1,1]);//方式2
$bool=Db::execute("insert into user values(null,:nickname,:username,:password,:zhuctime,:listtime)",['nickname'=>'马军辉','username'=>'888','password'=>'1','zhuctime'=>$time,'listtime'=>$time]);//方式3
dump($bool);
}



//删除User中数据
public function delete(){
//$bool=Db::execute("delete from user where id=1");
//$bool=Db::execute("delete from user where id>?",[5]);
$bool=Db::execute("delete from user where id>:id",['id'=>'3']);
dump($bool);
}


//修改表中数据
public function update(){
	$data=Db::execute("update user set nickname='无敌马军辉'where id='3'");
	
}



    
    
    
    //查询user表中数据
    public function select(){
//$data=Db::query("select*from user");
//占位符方式
$data=Db::query("select*from user where id>=? and id<=?",[1,99999999]);
$sql=Db::getLastsql();//获取最后一次执行的sql语句
dump($data);
dump($sql);
}
    }







#$
//模拟PUT请求必须格式
 <input type="hidden" name="_method" value="PUT"/>









#$
//传统sql语句Db类操作数据库
//资源路由生成的方法
<?php
namespace app\index\controller;
use think\Controller;
use think\Request;
use think\Db;
class User1 extends controller
{
	
	    //查询数据
    public function index()
    {
	$data=Db::query("select*from user");
	$this->assign("data",$data);
    	return view();
    }
    
    
 //create;创建新增数据
 public function create(){
 		$this->assign("data","[]"); 	return view();
 }
 
 
 //save方法专门保存post过来数据
 //保存post数据
 public function save(Request $request){
date_default_timezone_set('PRC');
$lasttime=date('Y-m-d H:i:s'); 	$inp=input("post.");

 	$cold=Db::execute("insert into user values('null',:nickname,:username,:password,:zhucetime,:lasttime)",['nickname'=>$inp['nickname'],'username'=>$inp['username'],'password'=>$inp['password'],'zhucetime'=>$lasttime,'lasttime'=>$lasttime]);
 //	dump($cold);
 	if($cold){
 		$this->success("添加数据成功","");
 	}else{
 		$this->error("添加失败");
 	}
 	}
 	
 	//edit方法更新用户提交
 	//负责查询并且输出原有数据和修改页面
 	public function edit($id){
 $data=Db::query("select*from user where id=?",[$id]);
	$this->assign("data",$data);
    return view();
    dump($data);
 		 	}
 	
 	//update方法保存用户更新的数据
 	public function update(Request $request,$id){
//仅仅获取想要的变量
$data=Request::instance()->only(['nickname','id']);
 		$cold=Db::execute("update user set nickname=:nickname where id=:id",$data); 			
 		}
 		
  		//delete方法删除数据
 		public function delete($id){
 		//	$data=input("id");
 			$bool=Db::execute("delete from user where id=$id"); 
 				}
    
   	//ajax删除数据
 		public function ajax_delete(){
 		$id=input("post.id/d");
 			$bool=Db::execute("delete from user where id=$id"); 
 			if($bool){
 				$data=['statu'=>'200','info'=>'删除成功'];
 			}else{
 							$data=['statu'=>'400','info'=>'删除失败'];
 			}
 			return $data;
 				}    
    
}//class







#$
//TP5的Db类里的方法操作数据库
1.table方法查询数据
  //查询user表中所有数据集
  Db::table("user")->select();
  //查询user表中一条数据
  Db::table("user")->find();

2.name方法查询数据
  //name和table区别在于name方法会自动    加上配置的表前缀
  //查询user表中所有数据集
  Db::name("user")->select();
  //查询user表中一条数据
  Db::name("user")->find();
  
3.条件匹配
  Db::table("user")->where("id",'<',5)->select();
  //在user表匹配id>5小于8的数据
  //$sql="select * from 'user' where('id'>5 and 'id'<8)";
  Db::table("user")->where("id",'>',5)->where("id","<",8)->select();
  
4.模糊匹配
//匹配name字段是user1的数据
  Db::table("user")->where("name",'like','%user1%')->select();
  
5.匹配账号密码完全一样的
Db::table("user")->where("username",'password')->("752","m6258")->select();
//$sql="select * from 'user'where 'username'='752'and 'password'='m6258'";




#$
//whereOr或者匹配
//匹配id>=5或者id<=8的
//$sql="select * from 'user' where 'id'>=5 or 'id'<=8 ";
  Db::table("user")->where("id",'>=',5)->whereOr("id","<=",8)->select();



  
  #$
  //limit截取数据
  //$sql="select * from 'user' limit 5";
  Db::table("user")->limit(5)->select();//一个参数从头截取5个
  
   //$sql="select * from 'user' limit 5,4";
  Db::table("user")->limit(5,4)->select();//从第五条开始截取4条
  
  
  
  #$
  //order排序,desc倒序，默认顺序
//$sql="select * from 'user' order BY'id'desc";
  Db::table("user")->order("id","desc")->select();
  
  
  
  
  #$
  //field设置查询字段
  //$sql="select 'id','password' from 'user' ";
  Db::table("user")->field("id，password")->select();
  //起别名uname
  //$sql="select name uname,'password' from 'user' ";
  Db::table("user")->find("name uname，password")->select();
  
  
  
  
  #$
  //sql系统函数使用
  //count()统计user表中一共多少条数据取别名为tot
  //$sql="select count(*) as tot from 'user' ";
  Db::table("user")->field("count(*) as tot")->select();
  //使用数组方式
Db::table("user")->field(['count(*)'=>'tot'])->select();



#$
//排除要查询的字段
//设置第二个参数为true排除name和id字段
Db::table("user")->field(['name','id'],true)->select();



#$
//page分页
//此方法自动计算页码
//第一页显示5条数据
//$sql="select *from 'user' like 1,5";
  Db::table("user")->page("1,5")->select();
  
  
  
  
  
 #$
 //group分组聚合
 //此处先统计pass字段所有数据,然后分组聚合出数据
 //$sql="select 'pass',count(*) tot from 'user' group BY pass ";
  Db::table("user")->field("pass,count(*)as tot")->group("pass")->select();
  
  
  
  
  
  #$
  //having过滤
  //配合分组聚合使用筛选数据
  //此处选出pass字段相同的数据超过五条的用户信息
 //$sql="select 'pass',count(*) tot from 'user' group BY pass having tot >=5";
 Db::table("user")->field("pass,count(*)as tot")->having("tot >=5")->group("pass")->select();
 
 
 
 
 #$
 //多表查询
 //此处查询商品表goods和分类表type
 //查询分类名称name字段并取别名tname
 //2表间关系是:goods表cid字段=type表的id字段
 //$sql="select goods.*,type.name tname from type,goods where goods.cid=type.id";
 Db::query("select goods.*,type.name tname from type,goods where goods.cid=type.id");
 
 
 
 
 
 #$
 //join内联多表查询
 //join关联type表,并且第二个参数为二者的关系goods.cid=type.id
 //查询goods表里的所有和type表里的名字name并且起个别名tname
 //别名就是给查询的结果起个新名字
//$sql="select 'goods'.*,type.name tname FROM 'goods' INNER JOIN 'type' 'type' ON 'goods'.'cid'='type'.'id'";
 Db::table("goods")->field("goods.*,type.name tname")->join("type","goods.cid=type.id")->select();
 
 
 
 //右联实现查询
 //join第三个参数设置'right'
 //以右边表为主
 //左连接改参数为left即可 
 //$sql="select 'goods'.*,type.name tname FROM 'goods' RIGHT JOIN 'type' 'type' ON 'goods'.'cid'='type'.'id'";
 Db::table("goods")->field("goods.*,type.name tname")->join("type","goods.cid=type.id",'right')->select();
 
 
 
 
 
 #$
 //别名的使用alias()
 //简短名字长度
 //$sql="select 'g'.*,t.name tname FROM 'g' RIGHT JOIN 'type' 't' ON 'g'.'cid'='t'.'id'";
 Db::table("goods")->alias('g')->field("g.*,t.name tname")->join("type t","g.cid=t.id",'right')->select();
 
 
 
 
 
 
 #$
 //union合并两个表查询的集合
 //$sql="select 'name' from 'user' UNION select name from goods";
 Db::field("name")->table("user")->union("select name from goods")->select();
 
 
 
 
 #$
 //bind绑定参数,防sql注入
 //防止sql逻辑注入
 //全转为int
 $sql="select from 'user' where id=24";
 Db::table('user')->where("id",":id")->bind(["id"=>[$id,\PDO::PARAM_INT]])->delete();
 
 
 
 
 #$
 //数据表数据统计
1.统计最大值(只能统计字段)
 //$sql="SELECT MAX(age) AS tp_max FROM 'user' LIMIT 1";
 Db::table("user")->max("age");
2.统计最小值(只能统计字段)
 //$sql="SELECT MIN(age) AS tp_min FROM 'user' LIMIT 1";
 Db::table("user")->min("age");
3.统计最平均值(只能统计字段)
 //$sql="SELECT AVG(age) AS tp_avg FROM 'user' LIMIT 1";
 Db::table("user")->avg("age");
 4.统计和(只能统计字段)
 //$sql="SELECT SUM(age) AS tp_sum FROM 'user' LIMIT 1";
 Db::table("user")->sum("age");
 5.统计总数(可统计表中数据)
 //$sql="SELECT count(age) AS tp_count FROM 'user' LIMIT 1";
 Db::table("user")->count("age");
 
 
 
 
 
 
 
 #$
 //数据库增;删;改操作
 1.插入数据
 //数组中的键名必须和表中字段名一致
 //返回值:影响行数
 //$sql="insert into 'user'('name','age')values('马军','24')";
 $data=["name"=>"马军","age"=>"24",];
 Db::table('uaer')->insert($data);

2.插入多条数据
 //$sql="insert into 'user'('name','age')values select '马军','24' UNION ALL select '王'，'25'";
 $data=[["name"=>"马军","age"=>"24"],['name'=>'王','age'=>'25'],];
 Db::table('uaer')->insertAll($data);

3.获取最后一次插入的ID
//返回值:最后插入的ID
//$sql="insert into 'user'('name','age')values('马军','24')";
 $data=["name"=>"马军","age"=>"24",];
 Db::table('uaer')->insertGetId($data);
 
 
 
 
 
 #$
 //更新数据
 //$sql="UPDATE 'user' SET 'pass'='m6258'where 'id'=5";
Db::table("user")->where('id',5)->update(['pass'=>'m6258']);

//更新某个字段的值
//$sql="UPDATE 'user' SET 'pass'='abc'where 'id'=6";
Db::table('user')->where('id','6')->setField('pass','abc');





#$
//设置某个字段自增或自减
//where条件=号可以省略
//设置id=5的age字段自增
$sql="update 'user' SET 'age'=age+1 where 'id'=5";
Db::table('user')->where('id',5)->serInc('age');

//自减
$sql="update 'user' SET 'age'=age-1 where 'id'=5";
Db::table('user')->where('id',5)->serDec('age');

//自定义要加减的值
$sql="update 'user' SET 'age'=age-3 where 'id'=5";
Db::table('user')->where('id',5)->serDec('age',3);





#$
//删除数据一条数据
$sql="DELETE FROM 'user' WHERE 'id'=9";
Db::table('user')->where('id','9')->delete();
Db::table('user')->delete(9);//同上

//删除多条数据
//删除id为2,3,5的数据
$sql="DELETE FROM 'user' WHERE (id in(2,3,5));
Db::table('user')->where('id in(2,3,5)')->delete();
Db::table('user')->delete([2,3,5]);//同上

//删除区间数据
$sql="DELETE FROM 'user' WHERE (id>3 and id<6);
Db::table('user')->where('id > 3 and id<6')->delete();









#$
//事物机制
//Mysql的事物要求数据库的引擎必须为InnoDB
1.使用transaction方法操作数据库事务，当发生异常会自动回滚，例如：
自动控制事务处理
Db::transaction(function(){
Db::table('think_user')->find(1);
Db::table('think_user')->delete(1);
});

手动控制事务，例如：
//启动事务
Db::startTrans();
//事务
try{
$a=Db::table('think_user')->find(1);
//如果操作失败抛出异常用Exception类接收
if(!$a){
	throw new \Exception("$a操作失败");
}
$b=Db::table('think_user')->delete(1);
if(!$b){
	throw new \Exception("$b操作失败");
}
echo "所有操作成功";
//提交事务
Db::commit();
}catch(\Exception$e){
//回滚事务
//$e中有好多方法待查看学习
echo "其中至少有一个操作失败";
dump($e->getMessage());//输出抛出的异常信息
Db::rollback();
}


//简化写法
//启动事务
Db::startTrans();
$a=Db::table('user')->delete(5);
$b=Db::table('user')->delete(6);
if($a&&$b){
	//如果操作数据成功则提交事务
	Db::commit();
}else{
	//否则回滚事务
	Db::rollback();
}
//注意:在事务操作的时候，确保你的数据库连接是相同的。








#$
//视图查询
//左右连接同多表查询
//可以使用数组和其他,详手册
//查询goods表字段id,name,price且关联type表,二表关系是type.id=goods.cid
$sql="SELECT 'goods'.'id','goods'.'name','goods'.'price',type.name tname FROM 'goods' 'goods' INNER JOIN 'type' 'type' ON 'type'.'id'='goods'.'cid'";

Db::view("goods","id,name,price")->view("type","name tname","goods.cid=type.id")->select();







#$
//Model数据模型里配置数据库
<?php          
namespace app\index\model;
use think\Model;
class User extends Model {
//设置当前模型对应的完整数据表名称
protected$table='user';
//设置当前模型的数据库连接
protected$connection=[
//数据库类型
'type'=>'mysql',
//服务器地址
'hostname'=>'127.0.0.1',
//数据库名
'database'=>'',
//数据库用户名
'username'=>'root',
//数据库密码
'password'=>'',
//数据库编码默认采用utf8
'charset'=>'utf8',
//数据库表前缀
'prefix'=>'think_',
//数据库调试模式
'debug'=>false,
];
}








#$
//第八章
//数据模型(Model)
<?php          
namespace app\index\model;
use think\Model;
class User extends Model {
	}//class
	
	注意:
	1.建议数据模型名跟数据库表名一致(默认找对应的表，不设置会报错)
	2.设置查询的数据表
	3.如果数据表名为_下划线名名,在Model中需驼峰写法
protected $table="user";



#$
//控制器中实例化模型
$user=new \app\Index\model\user;
//获取对象集中一条数据并转为数组
dump($user::get(1)->toArray());

//导入用户自定义数据模型类
use \app\Index\model\User;
//使用静态方法
User::get(1);

//实例化类
$user=new User();
//使用
$user::get(2);


//使用Loader类自动加载模型
use think\Loader;
$user=Loader::Model("user");
$res=$user::get(3);
dump($res->toArray());

//助手函数
$user=Model('user');
$user::get(4);




#$
//使用数据模型查询数据操作
//获取单条数据
$res=User::get(1);//默认主键
//查询name字段为majun的数据
$res=User::get(['name'=>'majun']);
//使用闭包函数查询
$res=User::get(function($query){
	$query->where('id',5);
});
//field方法
$res=User::where('id',5)->field();


//查询多条数据
$res=User::all();//默认查询所有
//遍历
foreach($res as $key=>$value){
	dump($value->toArray());
}
//查询指定
$res=User::all([3,5,8]);
$res=User::all(['pass'=>'m625']);
//使用闭包
//闭包可以更多的连贯操作，数组不能
$res=User::all(function($query){
	$query->where('pass',123)->whereOr('pass',456)->order('id','desc');
});

//select方法和all使用相同
$res=User::select();






#$
//获取某列或某个字段的值
//获取id为5的name字段的值
$res=User::where('id',5)->value('name');
//获取一列的值
$res=User::column('pass');
//获取多列
$res=User::column('pass','id');


#$
//动态查询
//根据字段查询用户
//查询密码字段是ww1的用户
$res=User::getByPass('ww1');




#$
//新增数据
//先实例化模型
$user=new User();
$user->name="马军";
$user->pass='m';
$user->save();//保存

//data方法新增数据
$user=data([
'name'=>'马军',
'pass'=>'m',
]);
$user->save();//保存

//实例化时操作
$user=new User([
'name'=>'马军',
'pass'=>'m',
]);
//allowField(true)屏蔽数据表中没有的字段。用以插入表单数据时过滤无用表单
$user->allowField(true)->save();

//指定字段的写入
//只插入name和pass字段,其余屏蔽
$user->allowField(["name","pass"])->save();

//获取自增的id
//获取的是模型的主键
//获取插入数据的id
$user->id;



//新增多条数据
$user= new User();
$list=[
['name'=>'majun','pass'=>'123'],
['name'=>'majun','pass'=>'123'],
];
$user->sevaAll($list);

//create静态方法插入
$user=User::create([]);




#$
//删除数据
删除id为2的数据
$user=User::get(2);
$user->delete();
//删除主键为3的数据
$user=User::destroy(3);
//删除主键3,4,5[]
$user=User::destroy("3,4,5");
//条件删除
$user=User::destroy(["name"=>"maj"])

destroy(["name"=>"maj",'age=>'55]);

  #$
  //闭包删除数据
  User::destroy(function($query){
  $query->where('id','<','5');
  });

#$
//数据库查询类删除数据
$user=User::where('id','>','19')->delete();

 #$
 //查找并更新数据
 
 $user=User::get(15);
 $user->name='mma';
 $user->save();
 //实例化后直接更新
 //save方法第二个参数为条件
 $user=new User();
 $user->seva(['name'=>'majun'],['id'=>'4']);
 
//过滤非数据表字段数据更新
//过滤post数组中的非数据表字段数据
$user=new User();
$user->allowField(true)->save($_POST,['id'=>'8']);
#$
//sevaAll方法批量更新
//此方法只能使用主键进行更新,其他情况请使用foreach遍历更新
$user=new User();
$list=[
['id'=>2,'name'=>'m1','pass'=>'55'],
['id'=>3,'name'=>'wzx','pass'=>'123'],
];
$user->sevaAll($list);

#$
//isUpdate(true)true为更新。false为新增
//遍历数组批量更新数据
$user=new User();
$list=[
['id'=>2,'name'=>'m1','pass'=>'55'],
['id'=>3,'name'=>'wzx','pass'=>'123'],
];
foreach($list as $data){
	$user->data($data,true)->isUpdate(true)->seva();
}
 
 
 #$
 //静态where方法更新数据
 User::where('id','>','9')->Update(['id'=>2,'name'='qw']);
 
 #$
//闭包更新数据
//实现更复杂的更新条件
$user=new User();
$user->seva(['name'=>'majun'],function($query){
	//更新status的值为5并且id小于10的name值为majun
	$query->where('status','>',5)->where('id','<',10');
});


#$
//数据模型聚合
//数据模型方式数据统计
//先得导入自定义数据模型

//统计User模型中总条数
$tot=User::count();
#$
//条件统计
//条件统计User模型中总条数
$tot=User::where('age','>',12)->count();
#$
//统计User模型中age的最大值
$max=User::max('age');
#$
//统计User模型中age的最小值
$min=User::min('age');
#$
//统计User模型中age的平均值
$avg=User::avg('age');
#$
//统计User模型中age的和
$sum=User::sum('age');
#$
//静态和动态调用数据模型
静态:
use \app\index\model\User;
User::方法名();
动态:$user=new User;
$user::方法名();





#$
//获取器
//获取数据时自动调用并返回对应数据
//getStatusAttr
//get表字段Attr
获取器的作用是在获取数据的字段值后自动进行处理，例如，我们需要对状态值进行转换，可以使用：
class User extends Model{
public function getStatusAttr($value)
{
$status=[-1=>'删除',0=>'禁用',1=>'正常',2=>'待审核'];
return $status[$value];
}
}
数据表的字段会自动转换为驼峰法，一般status字段的值采用数值类型，我们可以通过获取器定义，自
动转换为字符串描述。
$user=User::get(1);
echo$user->status;//例如输出“正常”
获取器还可以定义数据表中不存在的字段，例如：
classUserextendsModel
{
publicfunctiongetStatusTextAttr($value,$data)
{
$status=[-1=>'删除',0=>'禁用',1=>'正常',2=>'待审核'];
return$status[$data['status']];
}
}
获取器方法的第二个参数传入的是当前的所有数据数组。
我们就可以直接使用status_text字段的值了，例如：
$user=User::get(1);
echo$user->status_text;//例如输出“正常”

//获取器
获取器只有当获取某个数据属性的时候自动触发，如果你要获取包含获取器处理的全部数据属性的话，可
以使用下面的方法：
$user=User::get(1);
//获取全部获取器数据
dump($user->toArray());
获取原始数据
如果你定义了获取器的情况下，希望获取数据表中的原始数据，可以使用：
$user=User::get(1);
//通过获取器获取字段
echo$user->status;
//获取原始字段数据
echo$user->getData('status');
//获取全部原始数据
dump($user->getData());




#$
//修改器
修改器
修改器的作用是可以在数据赋值的时候自动进行转换处理，例如：
class User extends Model
{
publicfunctionsetNameAttr($value)
{
returnstrtolower($value);
}
}
如下代码实际保存到数据库中的时候会转为小写
$user=newUser();
$user->name='THINKPHP';
$user->save();
echo$user->name;//thinkphp
也可以进行序列化字段的组装：
classUserextendsModel
{
publicfunctionsetNameAttr($value,$data)
{
returnserialize($data);
}
}
修改器方法的第二个参数会自动传入当前的所有数据数组。
批量修改
除了赋值的方式可以触发修改器外，还可以用下面的方法批量触发修改器：
$user=newUser();
$data['name']='THINKPHP';
$data['email']='thinkphp@qq.com';
$user->data($data,true);
$user->save();
echo$user->name;//thinkphp
或者直接使用save方法触发，例如：
$user=newUser();
$data['name']='THINKPHP';
$data['email']='thinkphp@qq.com';
$user->save($data);
echo$user->name;//thinkphp





#$
//模型数据自动完成
数据自动完成指在不需要手动赋值的情况下对字段的值进行处理后写入数据库。
系统支持auto、insert和update三个属性，可以分别在写入、新增和更新的时候进行字段的自动
完成机制，auto属性自动完成包含新增和更新操作，例如我们定义User模型类如下：
namespaceapp\index\model;
usethink\Model;
classUserextendsModel
{
protected$auto=[];
protected$insert=['ip','status'=>1];
protected$update=['login_ip'];
protectedfunctionsetIpAttr()
{
returnrequest()->ip();
}
}
在新增数据的时候，会对ip和status字段自动完成或者处理。
$user=newUser;
$user->name='ThinkPHP';
$user->save();
echo$user->name;//thinkphp
echo$user->status;//1
在保存操作的时候，会自动完成ip字段的赋值。
$user=User::find(1);
$user->name='THINKPHP';
$user->save();
echo$user->name;//thinkphp
echo$user->ip;//127.0.0.1





 
 
 
 #$
//软删除
调整功能
5.0.2
deleteTime属性改为非静态定义
在实际项目中，对数据频繁使用删除操作会导致性能问题，软删除的作用就是把数据加上删除标记，而不
是真正的删除，同时也便于需要的时候进行数据的恢复。
要使用软删除功能，需要引入SoftDeletetrait，例如User模型按照下面的定义就可以使用软删除功
能：
namespace app\index\model;
use think\Model;
use traits\model\SoftDelete;
class User extends Model
{
use SoftDelete;
protected $deleteTime='delete_time';
}
5.0.2版本之前deleteTime属性必须使用static定义。
deleteTime属性用于定义你的软删除标记字段，ThinkPHP5的软删除功能使用时间戳类型（数据表
默认值为Null），用于记录数据的删除时间。
可以用类型转换指定软删除字段的类型，建议数据表的所有时间字段统一一种类型。
定义好模型后，我们就可以使用：
//软删除
User::destroy(1);
//真实删除
User::destroy(1,true);
$user=User::get(1);
//软删除
$user->delete();
//真实删除
$user->delete(true);
默认情况下查询的数据不包含软删除数据，如果需要包含软删除的数据，可以使用下面的方式查询：
User::withTrashed()->find();
User::withTrashed()->select();
如果仅仅需要查询软删除的数据，可以使用：
User::onlyTrashed()->find();
User::onlyTrashed()->select();
如果你的模型定义了base基础查询，请确保添加软删除的基础查询条件。

 
 
 
 
 #$
 //视图
 //渲染输出方式1:
 //需要导入系统控制器类并继承
 return this->fetch();
 方式2:
 //使用助手函数
 return view();
 #$
 //视图模板变量赋值
 方式1:assign方法,控制器中赋值变量
 $name="马军";
 $city='乌鲁木齐';
 //可使用数组批量赋值
 $this->assign('name',$name);//[]
 $this->assign('city',$city);//[]
 在html页面中接收数据:
 <h1>{$name}</h1>
 <h1>{$city}</h1>
 
//方式2:fetch()方法赋值
//fetch和view输出参数一样
//参数1"":输出模板文件名,默认对应不写即
//参数2[]:赋值的变量数组形式
//参数3[]:模板替换数组['__ADMIN'__=>'/static/admin/']
//参数4:: 
return $this->fetch('',['name'=>$nanam,'city'=>$city]);
 
 //对象赋值方式
 $this->view->name='马军';
  $this->view->city='乌鲁木齐';
 return view();
 
 
 
 
 
 #$
 //输出(模板)替换,简短页面中引入公共资源路径长度
输出替换
模板输出替换
版本
新增功能
5.0.4
增加__ROOT__
__STATIC__
__JS__和__CSS__内置替换规则
支持对视图输出的内容进行字符替换，例如：
namespaceindex\app\controller;
classIndexextends\think\Controller
{
publicfunctionindex()
{
$this->assign('name','thinkphp');
return$this->fetch('index',[],['__PUBLIC__'=>'/public/']);
}
}
如果需要全局替换的话，可以直接在配置文件中添加：
'view_replace_str'=>[
'__PUBLIC__'=>'/public/',
'__ROOT__'=>'/',
]
然后就可以直接使用
namespaceindex\app\controller;
classIndexextends\think\Controller
{
publicfunctionindex()
{
$this->assign('name','thinkphp');
return$this->fetch('index');
}
}
助手函数view也支持全局配置参数view_replace_str的设置，如果需要设置不同的替换参数，可
以使用：
return view('index',['name'=>'thinkphp'],['__PUBLIC__'=>'/public/']);
在渲染模板或者内容输出的时候就会自动根据设置的替换规则自动替换。
要使得你的全局替换生效，确保你的控制器类继承think\Controller或者使用view助手函数渲染输出。






#$
//模板标签
控制器输出数组
$arr=['name'=>'马','age'=>25];
return this->assign('data',$arr);
//html接收
{$data['name'];}
{$data.age;}

#$
//使用函数
//模板中接收变量
使用函数
我们往往需要对模板输出变量使用函数，可以使用：
{$data.name|md5}
编译后的结果是：
<?phpecho(md5($data['name']));?>
如果函数有多个参数需要调用，则使用：
{$create_time|date="y-m-d",###}
表示date函数传入两个参数，每个参数用逗号分割，这里第一个参数是y-m-d，第二个参数是前面要输
出的create_time变量，因为该变量是第二个参数，因此需要用###标识变量位置，编译后的结果是：
<?phpecho(date("y-m-d",$create_time));?>
如果前面输出的变量在后面定义的函数的第一个参数，则可以直接使用：
{$data.name|substr=0,3}
表示输出
<?phpecho(substr($data['name'],0,3));?>
虽然也可以使用：
{$data.name|substr=###,0,3}
但完全没用这个必要。
还可以支持多个函数过滤，多个函数之间用“|”分割即可，例如：
{$name|md5|strtoupper|substr=0,3}
编译后的代码:
<?phpecho(substr(strtoupper(md5($name)),0,3));?>
函数会按照从左到右的顺序依次调用。
如果你觉得这样写起来比较麻烦，也可以直接这样写：
{:substr(strtoupper(md5($name)),0,3)}
变量输出使用的函数可以支持内置的PHP函数或者用户自定义函数，甚至是静态方法。




#$
//html页面使用系统变量
系统变量
系统变量输出
普通的模板变量需要首先赋值后才能在模板中输出，但是系统变量则不需要，可以直接在模板中输出，系
统变量的输出通常以**{$Think**打头，例如：
{$Think.server.script_name}//输出$_SERVER['SCRIPT_NAME']变量
{$Think.session.user_id}//输出$_SESSION['user_id']变量
{$Think.get.pageNumber}//输出$_GET['pageNumber']变量
{$Think.cookie.name}//输出$_COOKIE['name']变量
支持输出$_SERVER、$_ENV、$_POST、$_GET、$_REQUEST、$_SESSION和
$_COOKIE变量。
常量输出
还可以输出常量
{$Think.const.APP_PATH}
或者直接使用
{$Think.APP_PATH}
配置输出
输出配置参数使用：
{$Think.config.default_module}
{$Think.config.default_controller}
语言变量
输出语言变量可以使用：
{$Think.lang.page_error}
{$Think.lang.var_error}


#$
//html中使用请求参数
请求参数
模板支持直接输出Request请求对象的方法参数，用法如下：
$Request.方法名.参数
例如：
{$Request.get.id}
{$Request.param.name}
以$Request.开头的变量输出会认为是系统Request请求对象的参数输出。
支持Request类的大部分方法，但只支持方法的第一个参数。
下面都是有效的输出：
//调用Request对象的get方法传入参数为id
{$Request.get.id}
//调用Request对象的param方法传入参数为name
{$Request.param.name}
//调用Request对象的param方法传入参数为user.nickname
{$Request.param.user.nickname}
//调用Request对象的root方法
{$Request.root}
//调用Request对象的root方法，并且传入参数true
{$Request.root.true}
//调用Request对象的path方法
{$Request.path}
//调用Request对象的module方法
{$Request.module}
//调用Request对象的controller方法
{$Request.controller}
//调用Request对象的action方法
{$Request.action}
//调用Request对象的ext方法
{$Request.ext}
//调用Request对象的host方法
{$Request.host}
//调用Request对象的ip方法
{$Request.ip}
//调用Request对象的header方法
{$Request.header.accept-encoding}


#$
//模板中使用三目运算
三元运算
模板可以支持三元运算符，例如：
{$status?'正常':'错误'}
{$info['status']?$info['msg']:$info['error']}
{$info.status?$info.msg:$info.error}
5.0版本还支持如下的写法：
{$varname.aa??'xxx'}
表示如果有设置$varname则输出$varname,否则输出'xxx'。解析后的代码为：
<?phpechoisset($varname['aa'])?$varname['aa']:'默认值';?>
{$varname?='xxx'}
表示$varname为真时才输出xxx。解析后的代码为：
<?phpif(!empty($name))echo'xxx';?>
{$varname?:'no'}
表示如果$varname为真则输出$varname，否则输出no。解析后的代码为：
<?phpecho$varname?$varname:'no';?>
{$a==$b?'yes':'no'}
前面的表达式为真输出yes,否则输出no，条件可以是==、===、!=、!==、>=、<=



#$
//包含文件
包含文件
在当前模版文件中包含其他的模版文件使用include标签，标签用法：
{includefile='模版文件1,模版文件2,...'/}
包含的模板文件中不能再使用模板布局或者模板继承。
使用模版表达式
模版表达式的定义规则为：模块@控制器/操作
例如：
{includefile="public/header"/}//包含头部模版header
{includefile="public/menu"/}//包含菜单模版menu
{includefile="blue/public/menu"/}//包含blue主题下面的menu模版
可以一次包含多个模版，例如：
{includefile="public/header,public/menu"/}
注意，包含模版文件并不会自动调用控制器的方法，也就是说包含的其他模版文件中的变量赋值需要
在当前操作中完成。
使用模版文件
可以直接包含一个模版文件名（包含完整路径），例如：
{includefile="../application/view/default/public/header.html"/}
路径以项目目录/public/路径下为起点
传入参数
无论你使用什么方式包含外部模板，Include标签支持在包含文件的同时传入参数，例如，下面的例子我
们在包含header模板的时候传入了title和keywords参数：
{includefile="Public/header"title="$title"keywords="开源WEB开发框架"/}
就可以在包含的header.html文件里面使用title和keywords变量，如下：
<htmlxmlns="http://www.w3.org/1999/xhtml">
<head>
<title>[title]</title>
<metaname="keywords"content="[keywords]"/>
</head>
上面title参数传入的是个变量$title，模板内的[title]最终会替换成$title的值，当然$title这个变量必须要
存在。
包含文件中可以再使用include标签包含别的文件，但注意不要形成A包含A，或者A包含B而B又包含A这
样的死循环。
注意：由于模板解析的特点，从入口模板开始解析，如果外部模板有所更改，模板引擎并不会重新编
译模板，除非在调试模式下或者缓存已经过期。如果部署模式下修改了包含的外部模板文件后，需要
把模块的缓存目录清空，否则无法生效。




#$
//模板内置标签
//遍历循环输出
标签属性:
name   为后天分配数据的变量名
id     循环的变量
offset 截取数据的起始位置
length 截取数据的长度
mod    奇偶数
empty$ 数据为空时要输出的
key    主键号(相当于索引数组的key)
{volist name="data" id="value"} {/volist}



#$
FOREACH标签
foreach标签类似与volist标签，只是更加简单，没有太多额外的属性，最简单的用法是：
{foreach$listas$vo}
{$vo.id}:{$vo.name}
{/foreach}
该用法解析后是最简洁的。
也可以使用下面的用法：
{foreachname="list"item="vo"}
{$vo.id}:{$vo.name}
{/foreach}
name表示数据源item表示循环变量。
可以输出索引，如下：
{foreachname="list"item="vo"}
{$key}|{$vo}
{/foreach}
也可以定义索引的变量名
{foreachname="list"item="vo"key="k"}
{$k}|{$vo}
{/foreach}


#$
//FOR标签
用法：
{forstart="开始值"end="结束值"comparison=""step="步进值"name="循环变量名"}
{/for}
开始值、结束值、步进值和循环变量都可以支持变量，开始值和结束值是必须，其他是可选。
comparison的默认值是lt，name的默认值是i，步进值的默认值是1，举例如下：
{forstart="1"end="100"}
{$i}
{/for}
解析后的代码是
for($i=1;$i<100;$i+=1){
echo$i;
}










#$
//双层volist遍历输出多表关联内容
控制器中:
$type=Db::table('type')->select();
foreach($type as $key=>&$value){
$value['goods']	=Db::table('goods')->where("cid=$value['id']")->select();
this->assign('type',$type);
}//foreach


html中:
{volist name='type' id='value'}
<h1>{$value.name}</h2>
   {volist name="value.goods" id="goods"}
 <p>{$goods.name} {$goods.price}</p>
    {/volist}{//二层}
{/volist}{//一层}









#$
//验证器
//先导入系统验证器类
//实例化验证器
$validate=new validate();
//定义规则和自定义提示信息







#$
//缓存
//使用缓存
//还可使用系统函数方式
1.先导入系统缓存类
use think\Cache;
2.设置缓存
成功返回true
//设置缓存名为userdata,值为$data
//默认2个参数为永久缓存,参数三有效期
$data=Db::table("user")->select();
Cache::set("userdata",$data,100);
 
 #$
 //读取缓存
$data=Cache::get("userdata");

 //删除缓存
 Cache::rm("userdata");
 
 //清空缓存
 Cache::clear();
 
 
 #$
//开发中缓存应用
public function select(){
	if($data=Cache::get('userdata')){
		//缓存存在执行
		
	}else{
		//不存在缓存则
$data=Db::table('user')->select();
Cache::set('userdata',$data,1000)
	}
	//分配数据
	this->assign('data',$data);
	return view();
}


#$
//SESSION的运用
//导入session类
use think\Session;
1.
//设置session
 session::set('name','马军'[]);

#$
//获取Session
 session::get('name');
 
#$
//判断session是否已设置
$bool=Session::has("name");
//助手函数判断
$bool=Session("?name");

#$
//删除sessio
//没有返回值
Session::delete('name');

#$
//清空Session
Session::clear();
//助手函数清空
session(null);


#$
//cookie
//引入cookie类
//设置cookie
cookie::set('name','value');
//读取cookie
cookie::get("name");
//判断cookie是否设置
cookie::has("name");
//删除cookie
cookie::delete('name');
//清空cookie
cookie::clear();




#$
//分页
1:控制器中代码
//paginate
//每页显示3条数据,设置为true时只显示上下页
$data=Db::table('user')->paginate(3,true);
//分配数据
$this->assign("data",$data);
return $this->fetch();
2:视图中代码
<table width='800px' align='conte' border='1'>
<th>姓名></th>
<th>年龄</th>
<th>留言</th>
{volist name="data" id='value'}
<tr>
<td>{$value.name}</td>
<td>{$value.age}</td>
<td>{$value.text}</td>
</tr>
{/volist}
</table>
{$data->render()}{//分页按钮}





#$
//文件上传
上传文件
ThinkPHP5.0对文件上传的支持更加简单。
内置的上传只是上传到本地服务器，上传到远程或者第三方平台的话需要自己扩展。
假设表单代码如下：
<formaction="/index/index/upload"enctype="multipart/form-data"method="post">
<inputtype="file"name="image"/><br>
<inputtype="submit"value="上传"/>
</form>
然后在控制器中添加如下的代码：
publicfunctionupload(){
//获取表单上传文件例如上传了001.jpg
$file=request()->file('image');
//移动到框架应用根目录/public/uploads/目录下
if($file){
$info=$file->move(ROOT_PATH.'public'.DS.'uploads');
if($info){
//成功上传后获取上传信息
//输出jpg
echo$info->getExtension();
//输出20160820/42a79759f284b767dfcb2a0197904287.jpg
echo$info->getSaveName();
//输出42a79759f284b767dfcb2a0197904287.jpg
echo$info->getFilename();
}else{
//上传失败获取错误信息
echo$file->getError();
}
}
}
move方法成功的话返回的是一个\think\File对象，你可以对上传后的文件进行后续操作。


#$
//多文件上传
<formaction="/index/index/upload"enctype="multipart/form-data"method="post">
<inputtype="file"name="image[]"/><br>
<inputtype="file"name="image[]"/><br>
<inputtype="file"name="image[]"/><br>
<inputtype="submit"value="上传"/>
</form>
控制器代码可以改成：
publicfunctionupload(){
//获取表单上传文件
$files=request()->file('image');
foreach($filesas$file){
//移动到框架应用根目录/public/uploads/目录下
$info=$file->move(ROOT_PATH.'public'.DS.'uploads');
if($info){
//成功上传后获取上传信息
//输出jpg
echo$info->getExtension();
//输出42a79759f284b767dfcb2a0197904287.jpg
echo$info->getFilename();
}else{
//上传失败获取错误信息
echo$file->getError();
}
}
}
上传验证
支持对上传文件的验证，包括文件大小、文件类型和后缀：
publicfunctionupload(){
//获取表单上传文件例如上传了001.jpg
$file=request()->file('image');
//移动到框架应用根目录/public/uploads/目录下
$info=$file->validate(['size'=>15678,'ext'=>'jpg,png,gif'])->move(ROOT_PATH.
'public'.DS.'uploads');
if($info){
//成功上传后获取上传信息
//输出jpg
echo$info->getExtension();
//输出20160820/42a79759f284b767dfcb2a0197904287.jpg
echo$info->getSaveName();
//输出42a79759f284b767dfcb2a0197904287.jpg
echo$info->getFilename();
}else{
//上传失败获取错误信息
echo$file->getError();
}
}


getSaveName方法返回的是图片的服务器文件地址，并不能直接用于图片的URL地址，尤其在
windows平台上必须做转换才能正常显示图片。
如果上传文件验证不通过，则move方法返回false。
验证参数
说明
size
上传文件的最大字节
ext
文件后缀，多个用逗号分割或者数组
type
文件MIME类型，多个用逗号分割或者数组
还有一个额外的自动验证规则是，如果上传的文件后缀是图像文件后缀，则会检查该文件是否是一个
合法的图像文件。
上传规则
默认情况下，会在上传目录下面生成以当前日期为子目录，以微秒时间的md5编码为文件名的文件，例
如上面生成的文件名可能是：
/home/www/upload/20160510/42a79759f284b767dfcb2a0197904287.jpg
我们可以指定上传文件的命名规则，使用rule方法即可，例如：
//获取表单上传文件例如上传了001.jpg
$file=request()->file('image');
//移动到服务器的上传目录并且使用md5规则
$file->rule('md5')->move('/home/www/upload/');
最终生成的文件名类似于：
/home/www/upload/72/ef580909368d824e899f77c7c98388.jpg
系统默认提供了几种上传命名规则，包括：
规则
描述
date
根据日期和微秒数生成
md5
对文件使用md5_file散列生成
sha1
对文件使用sha1_file散列生成
其中md5和sha1规则会自动以散列值的前两个字符作为子目录，后面的散列值作为文件名。
如果需要使用自定义命名规则，可以在rule方法中传入函数或者方法，例如：
//获取表单上传文件例如上传了001.jpg
$file=request()->file('image');
//移动到服务器的上传目录并且使用uniqid规则
$file->rule('uniqid')->move('/home/www/upload/');
生成的文件名类似于：
/home/www/upload/573d3b6d7abe2.jpg
如果你希望保留原文件名称，可以使用：
//获取表单上传文件例如上传了001.jpg
$file=request()->file('image');
//移动到服务器的上传目录并且使用原文件名
$file->move('/home/www/upload/','');
默认情况下，会覆盖服务器上传目录下的同名文件，如果不希望覆盖，可以使用：
//获取表单上传文件例如上传了001.jpg
$file=request()->file('image');
//移动到服务器的上传目录并且设置不覆盖
$file->move('/home/www/upload/',true,false);
获取文件hash散列值
可以获取上传文件的哈希散列值，例如：
//获取表单上传文件
$file=request()->file('image');
//移动到服务器的上传目录并且使用原文件名
$upload=$file->move('/home/www/upload/');
//获取上传文件的hash散列值
echo$upload->md5();
echo$upload->sha1();
v5.0.1以上版本可以统一使用hash方法获取文件散列值
//获取表单上传文件
$file=request()->file('image');
//移动到服务器的上传目录并且使用原文件名
$upload=$file->move('/home/www/upload/');
//获取上传文件的hash散列值
echo$upload->hash('sha1');
echo$upload->hash('md5');
返回对象
上传成功后返回的仍然是一个File对象，除了File对象自身的方法外，并且可以使用SplFileObject
的属性和方法，便于进行后续的文件处理。

















#$
//模板布局
//方式一适合全局模板布局
 1.在配置文件application\config.php
 中添加
'template'=>[
'layout_on'=>true,//开启
'layout_name'=>'layout',//设置布局文件名
]
 2.在view目录下创建base文件夹用以存放公共文件
 header.html
 lefts.html
 3.在view目录下创建layout.html
  内容:
  //引入
{include file="base/header"/}
{__CONTENT__}//替换动态页面
{include file="base/lefts"/}



//方式二

 
 
 
 
 #$
 //模板接收关联模型数据
 	{foreach $data as $value}
	<tr>
<td>{$value.id}</td>
<td>{$value.realname}</td>    
<td>{$value.idnumber}</td>
<td>{$value.memberaccount}</td>
<td>{$value.id}</td>
<td>{$value.phonenumber}</td>
{foreach $value.membersmoney as $money}
<td>{$money.money}</td>
<td><a href="">查看记录</a></td>
	 </tr>  
	{/foreach}
	{/foreach}
 
 
 
 
 
 #$
 
 
 
 
 
 
 
 
 
 
 
 
 
 #$
 //模型数据的访问
 1:外部访问(控制器中)用模型对象$model
 2:内部访问(模型中)用伪变量$this
 
 #$
 //TP5增更读删(CURD)
 //推荐使用静态方法
 1:增Create
   save($data=[]);
   添加单条,实例化方式,返回影响行数
  
   saveAll($data=[]);
   批量添加,实例化方式,返回模型对象数组
   
   create($data=[]);
   单条添加,静态方法,返回模型对象
 
 2:更update
 //必须设置更新条件
 //条件可以使用闭包完成复杂的条件
  save($data=[],$where=[]);
   更新单条,实例化方式,返回影响行数
  
  
  
   saveAll($data=[],true);
   批量更新,实例化方式,返回模型对象数组
   
   
   
   
   
   update($data=[],$where=[],$field=[只允许的字段]);
   
   Administrator::Update($d[],$w[],$f[]);
   
   闭包
   $where=function ($query) use ($id){
   $query->	where("id",$id);
   };
 单条更新,静态方法,返回模型对象
 
 3:读read
 
 
 4:删delete
 
 
 
 
 
 
 
 



 





 
 
  
  
  
  
  
  





  
  
  
  
  
  
  
  
  
  
  




  

  
  
  
  
  
  
  















